/**
 * Expression.java
 * Copyright (C) 2011 Yuanyan<yuanyan.cao@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
package edu.rabbit.kernel.schema;

import org.antlr.runtime.tree.CommonTree;

import edu.rabbit.DbErrorCode;
import edu.rabbit.DbException;
import edu.rabbit.schema.IBinaryExpression;
import edu.rabbit.schema.IExpression;
import edu.rabbit.schema.IMatchExpression;
import edu.rabbit.schema.IUnaryExpression;

/**
 * @author Yuanyan<yanyan.cao@gmail.com>
 * 
 */
public abstract class Expression implements IExpression {

    public static IExpression create(CommonTree ast) throws DbException {
        String op = ast.getText().toLowerCase();
        if ("bind".equals(op) || "bind_name".equals(op)) {
            return new BindParameter(ast);
        } else if ("column_expression".equals(op)) {
            return new ColumnExpression(ast);
        } else if ("null".equals(op)) {
            return new NullLiteral(ast);
        } else if ("blob_literal".equals(op)) {
            return new BlobLiteral(ast);
        } else if ("float_literal".equals(op)) {
            return new FloatLiteral(ast);
        } else if ("function_literal".equals(op)) {
            return new FunctionLiteral(ast);
        } else if ("integer_literal".equals(op)) {
            return new IntegerLiteral(ast);
        } else if ("string_literal".equals(op)) {
            return new StringLiteral(ast);
        } else if ("function_expression".equals(op)) {
            return new FunctionExpression(ast);
        } else if ("isnull".equals(op) || "notnull".equals(op)) {
            return new IsNullExpression(ast);
        } else if ("case".equals(op)) {
            return new CaseExpression(ast);
        } else if ("raise".equals(op)) {
            return new RaiseExpression(ast);
        } else if (IMatchExpression.Operation.decode(ast.getText()) != null) {
            return new MatchExpression(ast);
        } else if ("in_values".equals(op)) {
            return new InValuesExpression(ast);
        } else if ("in_table".equals(op)) {
            return new InTableExpression(ast);
        } else if ("between".equals(op)) {
            return new BetweenExpression(ast);
        } else if (IBinaryExpression.Operation.decode(ast.getText()) != null && ast.getChildCount() == 2) {
            return new BinaryExpression(ast);
        } else if (IUnaryExpression.Operation.decode(ast.getText()) != null && ast.getChildCount() == 1) {
            return new UnaryExpression(ast);
        } else if ("collate".equals(op)) {
            return new CollateExpression(ast);
        }
        throw new DbException(DbErrorCode.ERROR, "Invalid expression");
    }
    
    /* (non-Javadoc)
     * @see org.tmatesoft.rabbit.core.schema.IExpression#getValue()
     */
    public Object getValue() {
        return toString();
    }
}
